package models

import (
    "time"
    "volux/pkg/errors"
    "volux/pkg/validator"
)

// BdevType 块设备类型
type BdevType string

const (
    BdevTypeMalloc BdevType = "malloc"
    BdevTypeAio    BdevType = "aio"
    BdevTypeNVMe   BdevType = "nvme"
)

// Bdev 定义块设备结构
type Bdev struct {
    Name      string    `json:"name"`
    Type      BdevType  `json:"type"`
    SizeMB    uint64    `json:"size_mb"`
    Filename  string    `json:"filename,omitempty"`
    Transport string    `json:"transport,omitempty"`
    Traddr    string    `json:"traddr,omitempty"`
    CreatedAt time.Time `json:"created_at"`
    UpdatedAt time.Time `json:"updated_at"`
}

// Validate 实现验证器接口
func (b *Bdev) Validate() []validator.ValidationError {
    var errs []validator.ValidationError

    if !validator.ValidateName(b.Name) {
        errs = append(errs, validator.ValidationError{
            Field:   "name",
            Message: "invalid bdev name format",
        })
    }

    if b.SizeMB == 0 {
        errs = append(errs, validator.ValidationError{
            Field:   "size_mb",
            Message: "size must be greater than 0",
        })
    }

    switch b.Type {
    case BdevTypeAio:
        if b.Filename == "" {
            errs = append(errs, validator.ValidationError{
                Field:   "filename",
                Message: "filename required for aio bdev",
            })
        }
    case BdevTypeNVMe:
        if b.Traddr == "" {
            errs = append(errs, validator.ValidationError{
                Field:   "traddr",
                Message: "target address required for nvme bdev",
            })
        }
        if !validator.ValidateIPv4(b.Traddr) {
            errs = append(errs, validator.ValidationError{
                Field:   "traddr",
                Message: "invalid target address format",
            })
        }
    }

    return errs
}

// BeforeCreate 创建前的钩子
func (b *Bdev) BeforeCreate() error {
    if errs := b.Validate(); len(errs) > 0 {
        return errors.New(errors.ErrTypeParam, 400, "validation failed")
    }
    
    now := time.Now()
    b.CreatedAt = now
    b.UpdatedAt = now
    return nil
}

// BeforeUpdate 更新前的钩子
func (b *Bdev) BeforeUpdate() error {
    if errs := b.Validate(); len(errs) > 0 {
        return errors.New(errors.ErrTypeParam, 400, "validation failed")
    }
    
    b.UpdatedAt = time.Now()
    return nil
}
